﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections.ObjectModel;
using System.Threading;

namespace Music_Tag_Organizer
{
    public delegate void OnReadTracksCompleteDelegate(ObservableCollection<Track> tracks);
    public delegate void OnTrackReadDelegate(Track track, int count, int total);

    public delegate void OnWriteTracksCompleteDelegate();
    public delegate void OnTrackWriteDelegate(Track track, int count, int total);

    public class MusicHandler
    {

        public event OnReadTracksCompleteDelegate OnReadTracksComplete;
        public event OnTrackReadDelegate OnTrackRead;

        public event OnWriteTracksCompleteDelegate OnWriteTracksComplete;
        public event OnTrackWriteDelegate OnTrackWritten;

        public MusicHandler()
        {
        } // end constructor


        public void ReadTracksAsync(String dirName)
        {
            ThreadStart starter = delegate { ReadTracks(dirName); };
            new Thread(starter).Start();

        }
        private void ReadTracks(String dirName)
        {
            ObservableCollection<Track> tracks = new ObservableCollection<Track>();
            DirectoryInfo dir = new DirectoryInfo(dirName);
            Console.WriteLine("Reading {0} files", dir.GetFiles().Count().ToString());
            int Total = dir.GetFiles("*.*", SearchOption.AllDirectories).Count();

            int Count = 0;
            foreach (FileInfo file in dir.GetFiles("*.*", SearchOption.AllDirectories))
            {

                Console.WriteLine("Checking file: {0}", file.FullName);
                Count++;
                TagLib.File musicFile = null;
                TagLib.Tag tag = null;
                try
                {
                    musicFile = TagLib.File.Create(file.FullName);
                    tag = musicFile.GetTag(TagLib.TagTypes.Id3v2);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error: {0}", ex.Message.ToString());
                    continue;

                }


                Console.WriteLine("File is of type: {0}", musicFile.MimeType);
                Track track = new Track(file.FullName)
                {
                    MusicFile = musicFile
                };


                try
                {
                    track.Album = tag.Album.Trim('\0').TrimEnd();
                    track.ContributingArtist = tag.Performers.First().Trim('\0').TrimEnd();
                    track.ContributingArtist = track.ContributingArtist.Trim('\0').TrimEnd();
                    track.Title = tag.Title.Trim('\0').TrimEnd();
                    track.Title = track.Title.Trim('\0').TrimEnd();
                    track.Suggest();

                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error: {0}", ex.Message.ToString());

                }
                finally
                {
                    tracks.Add(track);

                    OnTrackRead(track, Count, Total);
                }


            }

            if (tracks.Count == 0)
            {
                tracks.Add(new Track("empty"));
            }

            OnReadTracksComplete(tracks);
        } // end readtracks
        public void WriteTracksAsync(ObservableCollection<Track> tracks)
        {
            ThreadStart starter = delegate { WriteTracks(tracks); };
            new Thread(starter).Start();
        }
        private void WriteTracks(ObservableCollection<Track> tracks)
        {

            int Count = 0;
            int Total = tracks.Count;

            lock (tracks)
            {

                foreach (Track track in tracks)
                {
                    OnTrackWritten(track, Count, Total);
                    track.Save();
                    Count++;
                }
            }

            OnWriteTracksComplete();
        }

    } // end class
} // end namespace
